package com.tiancheng.onecode.service.impl;

import cn.dev33.satoken.stp.SaLoginModel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiancheng.onecode.configuration.auth.StpKit;
import com.tiancheng.onecode.entity.PlatformMerchantUser;
import com.tiancheng.onecode.entity.Role;
import com.tiancheng.onecode.entity.User;
import com.tiancheng.onecode.exception.Asserts;
import com.tiancheng.onecode.mapper.PlatformMerchantUserMapper;
import com.tiancheng.onecode.mapper.UserMapper;
import com.tiancheng.onecode.model.auth.UserMerchantProfile;
import com.tiancheng.onecode.model.auth.UserSubjectProfile;
import com.tiancheng.onecode.model.request.admin.*;
import com.tiancheng.onecode.model.response.PageInfo;
import com.tiancheng.onecode.model.response.admin.MerchantUserQueryRes;
import com.tiancheng.onecode.model.response.admin.PlatformMerchantUserRoleQueryRes;
import com.tiancheng.onecode.service.IPlatformMerchantUserService;
import com.tiancheng.onecode.service.IUserRoleService;
import com.tiancheng.onecode.service.IUserService;
import com.tiancheng.onecode.utils.ShaUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: kellen
 * @Description:角色管理 service impl
 * @Date: create in 2024/12/9 18:22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private HttpServletResponse response;
    @Resource
    private IPlatformMerchantUserService platformMerchantUserService;
    @Resource
    private IUserRoleService userRoleService;


    @Override
    public void register(UserRegisterReq userRegisterReq) {
        Asserts.isTrue(userRegisterReq.getPassword().equals(userRegisterReq.getConfirmPassword()), "源密码与确认密码不一致！");
        final long count = this.count(new LambdaQueryWrapper<User>().eq(User::getPhone, userRegisterReq.getPhone()));
        Asserts.isTrue(count==0, "该账号已注册过，请登录！");

        //生成随机盐值
        final String salt = ShaUtils.getSalt();
        String finalPassword = ShaUtils.encryption(userRegisterReq.getPassword(), salt);
        final User user = new User();
        user.setUserName(userRegisterReq.getUserName());
        user.setPhone(userRegisterReq.getPhone());
        user.setEmail(userRegisterReq.getEmail());
        user.setSalt(salt);
        user.setPwd(finalPassword);
        user.setCreatedDt(LocalDateTime.now());
        user.setUserStatus(0);
        this.save(user);
    }

    @Override
    public UserSubjectProfile pwdLogin(UserPwdLoginReq userPwdLoginReq) {
        // 登录端：1-平台端，2-商家端
        final Integer loginSource = userPwdLoginReq.getLoginSource();
        final User one = this.getOne(new LambdaQueryWrapper<User>().eq(User::getPhone, userPwdLoginReq.getPhone()));
        Asserts.isTrue(one!=null,"用户不存在！");
        String salt=one.getSalt();
        String finalPassword = ShaUtils.encryption(userPwdLoginReq.getPassword(), salt);
        Asserts.isTrue(finalPassword.equals(one.getPwd()),"用户密码不正确！");

        // 校验成功，查询用户角色和权限
        final UserSubjectProfile userSubjectProfile = new UserSubjectProfile();
        userSubjectProfile.setId(one.getId());
        userSubjectProfile.setUserName(one.getUserName());
        userSubjectProfile.setUserStatus(one.getUserStatus());
        userSubjectProfile.setPhone(one.getPhone());

        // 查询登录用户所属商户
        final List<UserMerchantProfile> userMerchantProfiles = platformMerchantUserService.queryByUserId(one.getId());
        userSubjectProfile.setUserMerchants(userMerchantProfiles);
        StpKit.admin.login(one.getId(),
                new SaLoginModel().setDevice("PC")                // 此次登录的客户端设备类型, 用于[同端互斥登录]时指定此次登录的设备类型
                .setIsLastingCookie(true)        // 是否为持久Cookie（临时Cookie在浏览器关闭时会自动删除，持久Cookie在重新打开后依然存在）
                .setExtra("subjectProfile", userSubjectProfile)    // Token挂载的扩展参数 （此方法只有在集成jwt插件时才会生效）
                .setIsWriteHeader(true));         // 是否在登录后将 Token 写入到响应头
        userSubjectProfile.setToken(StpKit.admin.getTokenInfo().getTokenValue());
        return userSubjectProfile;
    }

    @Override
    public PageInfo<MerchantUserQueryRes> queryPage(MerchantUserQueryReq params) {
        IPage<User> page=new Page<>(params.getCurrentPage(),params.getPageSize());
        final IPage<MerchantUserQueryRes> pageResult = this.baseMapper.queryPage(page, params);
        final List<MerchantUserQueryRes> records = pageResult.getRecords();
        if(!CollectionUtils.isEmpty(records)){
            final List<PlatformMerchantUserRoleQueryRes> roles = userRoleService.queryByPmuIds(records.stream().map(MerchantUserQueryRes::getPlatformMerchantUserId).collect(Collectors.toList()));
            if(!CollectionUtils.isEmpty(roles)){
                for (MerchantUserQueryRes record : records) {
                    record.setUserRoles(roles.stream().filter(r->r.getPlatformMerchantUserId().equals(record.getPlatformMerchantUserId())).collect(Collectors.toList()));
                }
            }
        }
        return new PageInfo<>(pageResult.getCurrent(),pageResult.getSize(),pageResult.getTotal(),pageResult.getRecords());
    }

    @Transactional
    @Override
    public void addMerchantUser(PlatformMerchantUserAddReq params) {
        final List<PlatformMerchantUser> merchantUsers = platformMerchantUserService.list(new LambdaQueryWrapper<PlatformMerchantUser>().eq(PlatformMerchantUser::getPlatformMerchantId, params.getPlatformMerchantId())
                .eq(PlatformMerchantUser::getUserId, params.getUserId()));
        Asserts.isTrue(!CollectionUtils.isEmpty(merchantUsers),"已添加该用户为管理员，不要重复操作！");
        final PlatformMerchantUser pmu = new PlatformMerchantUser();
        pmu.setPlatformMerchantId(params.getPlatformMerchantId());
        pmu.setUserId(params.getUserId());
        pmu.setMerchantUserName(params.getMerchantUserName());
        pmu.setIsSuperAdmin(Objects.isNull(params.getIsSuperAdmin())?0:1);
        platformMerchantUserService.save(pmu);
        // 角色处理
        userRoleService.saveUserRole(pmu.getId(),params.getRoleIds());
    }

    @Override
    public MerchantUserQueryRes detail(Long platformMerchantUserId) {
        final MerchantUserQueryRes res = baseMapper.queryDetailByPmuId(platformMerchantUserId);
        if(Objects.nonNull(res)){
            final List<PlatformMerchantUserRoleQueryRes> roles = userRoleService.queryByPmuIds(Collections.singletonList(platformMerchantUserId));
            res.setUserRoles(roles);
        }
        return res;
    }

    @Override
    public MerchantUserQueryRes queryPlatformMerchantId(Long platformMerchantId) {
        final List<PlatformMerchantUser> merchantSuperAdminUsers = platformMerchantUserService.list(new LambdaQueryWrapper<PlatformMerchantUser>().eq(PlatformMerchantUser::getPlatformMerchantId, platformMerchantId)
                .eq(PlatformMerchantUser::getIsSuperAdmin, 1));
        if(!CollectionUtils.isEmpty(merchantSuperAdminUsers)){
            return detail(merchantSuperAdminUsers.get(0).getId());
        }
        return null;
    }
}
